package org.groupg.practice.data;

import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.longs.LongArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;

/**
 * 针对特定场景的进一步优化
 */
public class AdvancedOptimizations {

    /**
     * 使用 Flyweight 模式重用对象
     */
    public static class FlyweightDataStore {
        private final IntArrayList ids;
        private final LongArrayList timestamps;
        private final DoubleArrayList values;
        private final ObjectArrayList<String> labels;
        private final DataRecord flyweightRecord;

        public FlyweightDataStore(int capacity) {
            this.ids = new IntArrayList(capacity);
            this.timestamps = new LongArrayList(capacity);
            this.values = new DoubleArrayList(capacity);
            this.labels = new ObjectArrayList<>(capacity);
            this.flyweightRecord = new DataRecord(0, 0, 0, null);
        }

        /**
         * 使用Flyweight模式获取记录，避免创建新对象
         */
        public DataRecord getRecordFlyweight(int index) {
            if (index < 0 || index >= ids.size()) return null;

            flyweightRecord.setId(ids.getInt(index));
            flyweightRecord.setTimestamp(timestamps.getLong(index));
            flyweightRecord.setValue(values.getDouble(index));
            flyweightRecord.setLabel(labels.get(index));

            return flyweightRecord;
        }
    }

    /**
     * 数据压缩存储 - 对重复字符串使用字典编码
     */
    public static class CompressedDataStore {
        private final IntArrayList ids;
        private final LongArrayList timestamps;
        private final DoubleArrayList values;
        private final IntArrayList labelCodes; // 字符串字典编码
        private final ObjectArrayList<String> labelDictionary;
        private final it.unimi.dsi.fastutil.objects.Object2IntMap<String> dictionaryIndex;

        public CompressedDataStore(int capacity) {
            this.ids = new IntArrayList(capacity);
            this.timestamps = new LongArrayList(capacity);
            this.values = new DoubleArrayList(capacity);
            this.labelCodes = new IntArrayList(capacity);
            this.labelDictionary = new ObjectArrayList<>();
            this.dictionaryIndex = new it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap<>();
        }

        public void addRecord(int id, long timestamp, double value, String label) {
            ids.add(id);
            timestamps.add(timestamp);
            values.add(value);

            // 字典编码压缩字符串
            int code = dictionaryIndex.getOrDefault(label, -1);
            if (code == -1) {
                code = labelDictionary.size();
                labelDictionary.add(label);
                dictionaryIndex.put(label, code);
            }
            labelCodes.add(code);
        }

        public String getLabel(int index) {
            int code = labelCodes.getInt(index);
            return labelDictionary.get(code);
        }
    }
}